import cgi
import datetime
import urllib
import webapp2

from google.appengine.ext import db
from google.appengine.api import users


# The following defines a data model for a greeting.
class Greeting(db.Model):
  """Models an individual Guestbook entry with an author, content, and date."""
  author = db.StringProperty()
  content = db.StringProperty(multiline=True)
  date = db.DateTimeProperty(auto_now_add=True)
  # This defines a Greeting model with three properties: 
  # author whose value is a string, content whose value is another string, 
  # and date whose value is a datetime.datetime.

def guestbook_key(guestbook_name=None):
  """Constructs a Datastore key for a Guestbook entity with guestbook_name."""
  return db.Key.from_path('Guestbook', guestbook_name or 'default_guestbook')


class MainPage(webapp2.RequestHandler):
  def get(self):
    self.response.out.write('<html><body>')
    guestbook_name=self.request.get('guestbook_name')

    # Ancestor Queries, as shown here, are strongly consistent with the High
    # Replication Datastore. Queries that span entity groups are eventually
    # consistent. If we omitted the ancestor from this query there would be a
    # slight chance that greeting that had just been written would not show up
    # in a query.
    # Get only the greetings posted in the past seven days
    # Display the last 10 greetings only (done by "LIMIT 10")
    # All GQL queries start with SELECT * FROM Greeting 
    greetings = Greeting.gql(
            "WHERE ANCESTOR IS :1 AND date > :2 ORDER BY date DESC LIMIT 10",
            guestbook_key(guestbook_name),
            datetime.datetime.now() + datetime.timedelta(days=-7))

    for greeting in greetings:
      if greeting.author:
        self.response.out.write(
            '<b>%s</b> wrote:' % greeting.author)
      else:
        self.response.out.write('An anonymous person wrote:')
      self.response.out.write('<blockquote>%s</blockquote>' %
                              cgi.escape(greeting.content))

    # Write the submission form and the footer of the page
    self.response.out.write("""
          <form action="/sign?%s" method="post">
            <div><textarea name="content" rows="3" cols="60"></textarea></div>
            <div><input type="submit" value="Sign Guestbook"></div>
          </form>
          <hr>
          <form>Guestbook name: <input value="%s" name="guestbook_name">
          <input type="submit" value="switch"></form>
        </body>
      </html>""" % (urllib.urlencode({'guestbook_name': guestbook_name}),
                          cgi.escape(guestbook_name)))


# Creates new greetings and saves them to the Datastore
class Guestbook(webapp2.RequestHandler):
  def post(self):
    # We set the same parent key on the 'Greeting' to ensure each greeting is in
    # the same entity group. Queries across the single entity group will be
    # consistent. However, the write rate to a single entity group should
    # be limited to ~1/second.
    guestbook_name = self.request.get('guestbook_name')
    greeting = Greeting(parent=guestbook_key(guestbook_name))

    user = users.get_current_user()
    if user:
      greeting.author = user.nickname()
    # Else we allow anonymous greetings.

    greeting.content = self.request.get('content')

    # Finally, greeting.put() saves our new object to the Datastore. 
    # If we had acquired this object from a query, put() would have updated the 
    # existing object. Since we created this object with the model constructor, 
    # put() adds the new object to the Datastore.
    greeting.put()

    self.redirect('/?' + urllib.urlencode({'guestbook_name': guestbook_name}))


myapp = webapp2.WSGIApplication([('/', MainPage),
                                ('/sign', Guestbook)],
                                debug=True)